#include "head.h"
// 数据操作的定义

//  顺序表的创建：
Sql_list *Init_Sql_List()
{
    // 动态分配内存
    Sql_list *L = (Sql_list *)malloc(sizeof(Sql_list));

    // 安全判断
    if (L == NULL)
    {
        printf("动态内存创建失败!\n");
    }

    L->data = (ticket_data *)malloc(sizeof(ticket_data) * MAX_SIZE);

    // 安全判断
    if (L->data == NULL)
    {
        printf("动态内存创建失败!\n");
    }

    // 初始化len和max
    L->len = 0;
    L->max = MAX_SIZE;
    return L;
}

// 顺序表的销毁
void Destroy_Sql_List(Sql_list **L)
{
    // 判空
    IsEmpty_Sql_List(*L);
    // 先销毁data的地址
    free((*L)->data);
    (*L)->data = NULL;
    // 再释放L
    free(*L);
    *L = NULL;
    printf("顺序表已经销毁!\n");
}

// 顺序表的判空
void IsEmpty_Sql_List(Sql_list *L)
{
    if (NULL == L)
    {
        ERRLOG("顺序表为NULL");
        return;
    }

    if (NULL == L->data)
    {
        ERRLOG("顺序表里面的数据为NULL");
        return;
    }

    if (L->len == 0)
    {
        ERRLOG("顺序表数据为空");
        return;
    }
}

// 顺序表的判满
void IsFull_Sql_List(Sql_list *L)
{
    if (L->len == MAX_SIZE)
    {
        printf("顺序表已满!\n");
        return;
    }
}

// 顺序表的查找：
// 按用户名查找对应所有的航班信息
void user_order_tickets(Sql_list *L, char *name)
{
    system("clear");
    IsEmpty_Sql_List(L);
    int num = count_line(USER_TICKET);//获取用户订票信息文件总行数
    int i = 0;
    int ticket = 0;//记录票数
    printf("下单时间                        班次        机型            起点站      终点站          起飞时间        到达时间    飞行时间    票价    机舱\n");
    printf("------------------------------------------------------------------------------------------------------------------------------------------------\n");
    // 找到对应名字的下标
    for (i = 0; i < num; i++)
    {
        if (!strcmp(name, L->data[i].name)) // 注意在C语言中字符串的比较需要用strcmp函数
        {
            //打印对应的信息
            printf_time_ticket(L->data[i]);
            ticket++;
        }
    }
    if (ticket==0) // 注意在C语言中字符串的比较需要用strcmp函数
    {
        // 打印对应的信息
        text_center("你尚未购买机票!\n",RED);
    }
    char ch = ' ';
    while (10 != ch)
    {
        sleep(1); // 当前进程进入休眠态 S
        ch = getchar();
    }
    return;
}

/** 尾插
 * 函数名 tail_del_list
 * 参数
 *      @L      需要插入的 静态表
 *      @data   需要插入的 数据项
 * 返回值
 *      无
 * 功能
 *      对静态表进行尾插
 */
void tail_insert_sqlist(Sql_list *L, ticket_data data)
{
    // 判满
    IsFull_Sql_List(L);
    // 插入
    L->data[L->len] = data;
    // 迭代
    L->len++;
    ticket_data_file_print(L,"w+");//写入到文件
    return;
}

/** 尾删
 * 函数名 tail_del_list
 * 参数
 *      @L 需要尾删的 静态表
 * 返回值
 *      无
 * 功能
 *      对静态表进行尾删
 */
void tail_del_sqlist(Sql_list *L)
{
    // 判空
    IsEmpty_Sql_List(L);
    // 减减
    L->len--;
}

// 按航班班次和名字删除
void pos_del_sqlist(Sql_list *L, int id,char *name)
{
    //从文件中读取
    ticket_data_file_scanf(L);
    // 判空
    IsEmpty_Sql_List(L);
    int pos = 1;
    int num = 0;
    //找到对应航班班次的在顺序表中的位置
    num = count_line(USER_TICKET);  //获取用户购票信息行数
    for (int i = 0; i < num; i++)
    {
        if (L->data[i].id == id && !(strcmp(L->data[i].name, name))) // 找到对应下标和名字的机票信息
        {
           break;
        }
        else if (!(L->data[i].id == id && !(strcmp(L->data[i].name, name))))
        {
            pos++;
        }    
    }
    // 判断删除位置是否合理
    if (strcmp(L->data[pos-1].name, name)||id!=L->data[pos-1].id)
    {
        text_center("没有找到对应班次用户的机票信息!\n",RED);
        return;
    }

    // Index=L.len直接尾删
    if (L->len == pos)
    {
        L->len--;
        ticket_data_file_print(L,"w+");//写入到文件
        return;
    }
    // 任意位置删除
    // 前移
    for (int i = pos-1; i < L->len; i++)
    {
        L->data[i] = L->data[i + 1]; // 从最后一个元素一直往前移动到删除位置
    }

    // 删除完成,表长减1
    L->len--;
    ticket_data_file_print(L, "w+"); // 写入到文件
    return;
}

// 判断用户是否重复购票
int is_buy_ticket(Sql_list *L, int id, char *name)
{
    // 判空
    IsEmpty_Sql_List(L);
    int num = 0;
    // 找到对应航班班次的在顺序表中的位置
    num = count_line(USER_TICKET); // 获取用户购票信息行数
    for (int i = 0; i < num; i++)
    {
        if (L->data[i].id == id && !(strcmp(L->data[i].name, name))) // 找到对应下标和名字的机票信息
        {
            text_center("您已购买该班次机票，请勿重复购买!\n", RED);
            return 0;
        }
    }
    return 1;
}
// 顺序表的清空：
void Clear_Sql_List(Sql_list *L)
{
  
}

/** 遍历打印
 * 函数名 printf_Sql_List
 * 参数
 *      @L 需要遍历的 静态表
 * 返回值
 *      无
 * 功能
 *      对静态表进行打印
 */
void printf_Sql_List(Sql_list *L)
{
    // 判空则不打印
    IsEmpty_Sql_List(L);
    printf("班次    机型        起点站  终点站  起飞时间    到达时间    飞行时间    票价  \n");
    printf("--------------------------------------------------------------------------\n");
    for (int i = 0; i < L->len; i++)
    {
        printf("%-6d",  L->data[i].id);
        printf("%-15s", L->data[i].flighttype);
        printf("%-10s", L->data[i].startcity);
        printf("%-10s", L->data[i].arrivecity);
        printf("%02d:%02d\t", L->data[i].starttime[0], L->data[i].starttime[1]);
        printf("%02d:%02d\t    ", L->data[i].arrivetime[0], L->data[i].arrivetime[1]);
        printf("%-10s\t", L->data[i].flytime);
        printf("%-6d\n", L->data[i].value);
    }
    return;
}

// 打印一条航班信息数据
void printf_ticket_data(ticket_data data)
{
    printf("%-6d", data.id);
    printf("%-15s", data.flighttype);
    printf("%-10s", data.startcity);
    printf("%-10s", data.arrivecity);
    printf("%02d:%02d\t", data.starttime[0], data.starttime[1]);
    printf("%02d:%02d\t    ", data.arrivetime[0], data.arrivetime[1]);
    printf("%-10s\t", data.flytime);
    printf("%-6d\n", data.value);
    return;
}

//打印有下单时间的机票信息
void printf_time_ticket(ticket_data data)
{
    printf("%s\t", data.order_time);
    printf("%-6d\t", data.id);
    printf("%-15s\t", data.flighttype);
    printf("      %-10s\t", data.startcity);
    printf("%-10s\t", data.arrivecity);
    printf("%02d:%02d\t\t", data.starttime[0], data.starttime[1]);
    printf("%02d:%02d\t    ", data.arrivetime[0], data.arrivetime[1]);
    printf("%-10s\t", data.flytime);
    printf("%-6d\t", data.value);
    printf("%s\n", data.cabin);
    return;
}

// 将用户订单写入到文件
void ticket_data_file_print(Sql_list *list,const char *mode)
{
    // 安全判断
    IsEmpty_Sql_List(list);
    // 打开文件
    FILE *fp = fopen(USER_TICKET, mode);
    // 安全判断
    if (NULL == fp)
    {
        ERRLOG("文件打开失败");
        return;
    }
    // 移动光标到开头
    fseek(fp, 0, SEEK_SET);
    // 遍历写入
    for (int i = 0; i < list->len; i++)
    {
        fprintf(fp, "%s\t\t\t", list->data[i].order_time);
        fprintf(fp, "%d\t\t", list->data[i].id);
        fprintf(fp, "%s\t\t", list->data[i].name);
        fprintf(fp, "%s\t\t", list->data[i].flighttype);
        fprintf(fp, "%s\t", list->data[i].startcity);
        fprintf(fp, "%s\t", list->data[i].arrivecity);
        fprintf(fp, "%d:%d\t\t", list->data[i].starttime[0], list->data[i].starttime[1]);
        fprintf(fp, "%d:%d\t\t", list->data[i].arrivetime[0], list->data[i].arrivetime[1]);
        fprintf(fp, "%s\t\t\t", list->data[i].flytime);
        fprintf(fp, "%d\t\t", list->data[i].value);
        fprintf(fp, "%s\t\t\n", list->data[i].cabin);
    }
    fflush(fp); // 刷新文件
    fclose(fp);
    return;
}


// 将用户订单从文件中读取
void ticket_data_file_scanf(Sql_list *list)
{
    // 安全判断
    IsEmpty_Sql_List(list);
    // 打开文件
    FILE *fp = fopen(USER_TICKET, "r");
    // 安全判断
    if (NULL == fp)
    {
        ERRLOG("文件打开失败");
        return;
    }
    //清空顺序表中的数据
    // for (int i = 0; i < list->len; i++)
    // {
    //     list->len = 0;
    // }
    int num = count_line(USER_TICKET);
    list->len = num;
    // 移动光标到开头
    fseek(fp, 0, SEEK_SET);
    // 遍历写入
    for (int i = 0; i < num; i++)
    {
        fscanf(fp, "%s\t\t\t", list->data[i].order_time);
        fscanf(fp, "%d\t\t", &list->data[i].id);
        fscanf(fp, "%s\t\t", list->data[i].name);
        fscanf(fp, "%s\t\t", list->data[i].flighttype);
        fscanf(fp, "%s\t", list->data[i].startcity);
        fscanf(fp, "%s\t", list->data[i].arrivecity);
        fscanf(fp, "%d:%d\t\t", &list->data[i].starttime[0], &list->data[i].starttime[1]);
        fscanf(fp, "%d:%d\t\t", &list->data[i].arrivetime[0], &list->data[i].arrivetime[1]);
        fscanf(fp, "%s\t\t\t", list->data[i].flytime);
        fscanf(fp, "%d\t\t\n", &list->data[i].value);
        fscanf(fp, "%s\t\t\n", list->data[i].cabin);
    }
    fflush(fp); // 刷新文件
    fclose(fp);
    return;
}
